package org.mtree.context.wrapper;

import java.util.Collection;
import java.util.function.Supplier;

import org.mtree.context.Context;

/**
 * 封装线程存储上下文
 * 
 * @author rushman
 * @date 2017-11-04
 */
public class ThreadContextWrapper implements Context {

    private final ThreadLocal<Context> contextLocal;
    private final Supplier<Context> supplier;

    public ThreadContextWrapper(Supplier<Context> contextSupplier) {
        super();
        this.contextLocal = new ThreadLocal<>();
        this.supplier = contextSupplier;
    }

    private Context getCurrentContext() {
        Context context = contextLocal.get();
        if (context == null) {
            synchronized (this.supplier) {
                context = this.supplier.get();
            }
            contextLocal.set(context);
        }
        return context;
    }

    @Override
    public Object get(String name) {
        return getCurrentContext().get(name);
    }

    @Override
    public Object set(String name, Object value) {
        return getCurrentContext().set(name, value);
    }

    @Override
    public Object remove(String name) {
        return getCurrentContext().remove(name);
    }

    @Override
    public boolean has(String name) {
        return getCurrentContext().has(name);
    }

    @Override
    public Collection<String> nameSet() {
        return getCurrentContext().nameSet();
    }

}
